package com.zxd.interview.jdk11;


import javax.crypto.KeyAgreement;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.NamedParameterSpec;
import java.security.spec.XECPublicKeySpec;

/**
 * XECPublicKey 和 XECPrivateKey
 * RFC7748定义的秘钥协商方案更高效, 更安全. JDK增加两个新的接口
 */
public class XECPublicKeyAndXECPrivateKeyTest {
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeySpecException, InvalidKeyException {
        generateKeyPair();
    }

    private static void generateKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeySpecException, InvalidKeyException {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
        NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
        kpg.initialize(paramSpec);
        KeyPair kp = kpg.generateKeyPair();
        PublicKey publicKey = generatePublic(paramSpec);
        generateSecret(kp, publicKey);
    }

    private static void generateSecret(KeyPair kp, PublicKey pubKey) throws InvalidKeyException, NoSuchAlgorithmException {
        KeyAgreement ka = KeyAgreement.getInstance("XDH");

        ka.init(kp.getPrivate());

        ka.doPhase(pubKey, true);

        byte[] secret = ka.generateSecret();
        // [B@10a035a0
        System.out.println(secret);
    }

    private static PublicKey generatePublic(NamedParameterSpec paramSpec) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory kf = KeyFactory.getInstance("XDH");

        BigInteger u = new BigInteger("111");

        XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);

        PublicKey pubKey = kf.generatePublic(pubSpec);
        return pubKey;
    }
}
